package znet

import (
	"fmt"
	"net"
	ziface "zinx/Ziface"
)

// 封装链接，本质是封装TCP套接字
type Connection struct {
	Conn       *net.TCPConn
	ConnID     uint32
	IsClose    bool
	ExitChan   chan bool //bool类型的管道
	//该链接的处理方法
	Router  ziface.IRouter
}

// 初始化链接的方法
func NewConnection(conn *net.TCPConn, connid uint32, router ziface.IRouter) *Connection {
	c := &Connection{
		Conn:       conn,
		ConnID:     connid,
		IsClose:    false,
		ExitChan:   make(chan bool, 1),
		Router: router,
	}
	return c
}

func (con *Connection) StartReader() {
	fmt.Println("Reader Goroutine is running...")
	defer fmt.Println("ConnID=", con.ConnID, "reader is exit,remote addr is ", con.GetRemoteAddr().String())
	defer con.Stop()

	//处理业务
	for {

		buf := make([]byte, 512)
		_, err := con.Conn.Read(buf)
		if err != nil {
			fmt.Println("recv buff err", err)
			break
		}
		//得到当前conn数据的request请求数据
		req:=Request{
			conn: con,
			data: buf,
		}


		//从路由中，找到注册的Conn对应的router调用方法
		go func (request ziface.IRuquest)  {

			con.Router.PreHandler(request)
			con.Router.Handler(request)
			con.Router.PostHandler(request)
		}(&req)

	}
}

// 启动链接，让当前的链接准备工作
func (con *Connection) Start() {
	fmt.Println("Conn Start()....ConnID", con.ConnID)

	//用两个协程，一个读协程，一个写协程
	go con.StartReader()

}

// 停止链接，结束当前链接的工作
func (con *Connection) Stop() {
	//关闭套接字
	fmt.Println("Conn Stop()....ConnID=", con.ConnID)

	if con.IsClose == true {
		return
	}

	con.IsClose = true
	con.Conn.Close()
	close(con.ExitChan)
}

// 获取当前链接的绑定套接字  conn
func (con *Connection) GetTCPConnection() *net.TCPConn {

	return con.Conn

}

// 获取当前链接的ID
func (con *Connection) GetID() uint32 {
	return con.ConnID
}

// 获取远程客户端的状态
func (con *Connection) GetRemoteAddr() net.Addr {
	return con.Conn.RemoteAddr()
}

// 发送数据
func (con *Connection) Send(data []byte) error {
	return nil
}
